﻿using System;
using GGameFramework;
using GGameFramework.Core.Pool;
using UnityEngine;

namespace GGFramework.Core.Timer
{
    // 计时器基类
    public abstract class TimerBase : ReferencePoolable,ITimer
    {
        public int ID { get; set; }
        public float Duration { get; protected set; }
        public float RemainingTime { get; protected set; }
        public bool IsPaused { get; protected set; }
        public bool IgnoreTimeScale { get; set; } = false;
        public Action Callback { get; set; }
        public Action<int> UpdateCallback { get; set; }
        public int LoopCount { get; set; } = 1;
        public float ElapsedTime { get; protected set; }
        public bool IsCompleted { get; protected set; }
        
        public abstract bool IsExpired { get; }
        
        protected int currentLoop = 0;

        public TimerBase(float duration)
        {
            Duration = duration;
            RemainingTime = duration;
        }

        public virtual void Pause() => IsPaused = true;
        public virtual void Resume() => IsPaused = false;
        public abstract void Cancel();

        public virtual void Reset()
        {
            RemainingTime = Duration;
            ElapsedTime = 0;
            currentLoop = 0;
            IsPaused = false;
            IsCompleted = false;
        }

        public virtual void Update(float deltaTime)
        {
            if (IsPaused || IsCompleted) return;

            ElapsedTime += deltaTime;
            RemainingTime -= deltaTime;
            UpdateCallback?.Invoke((int)RemainingTime);
        }

        protected virtual void Complete()
        {
            try
            {
                Callback?.Invoke();
            }
            catch (Exception e)
            {
                Debug.LogError($"Timer callback error: {e}");
            }
        }

        public override void OnSpawn()
        {
            Reset();
        }

        public override void OnRecycle()
        {
            base.OnRecycle();
            Callback = null;
            UpdateCallback = null;
        }

        public void Clear()
        {
            
        }
    }
}